﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TugasAkhir.Helpers
{
    public class KoefisienKorelasi
    {
        private int ukuranPopulasi;
        private List<int> skorItem;
        private List<int> skorItemKuadrat;
        private List<int> skorTotalItem;
        private List<int> skorTotalItemKuadrat;

        #region Properties
        public int UkuranPopulasi
        {
            get { return this.ukuranPopulasi; }
            set
            {
                //this.ukuranPopulasi = (int)Math.Ceiling(((double)value / (1.0 + ((double)value * Math.Pow(0.05, 2)))));
                this.ukuranPopulasi = value;
            }
        }

        public List<int> SkorItem
        {
            get { return this.skorItem; }
            set
            {
                this.skorItem = value;
                value.ForEach(item => this.skorItemKuadrat.Add((int)Math.Pow(item, 2.0)));
            }
        }

        public List<int> SkorTotalItem
        {
            get { return this.skorTotalItem; }
            set
            {
                this.skorTotalItem = value;
                value.ForEach(item => this.skorTotalItemKuadrat.Add((int)Math.Pow(item, 2.0)));
            }
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Konstruktor kosong
        /// </summary>
        public KoefisienKorelasi()
        {
            this.skorItem = new List<int>();
            this.skorItemKuadrat = new List<int>();
            this.skorTotalItem = new List<int>();
            this.skorTotalItemKuadrat = new List<int>();
        }

        /// <summary>
        /// Konstruktor dengan parameter ukuran populasi
        /// </summary>
        /// <param name="ukuranPopulasi"></param>
        public KoefisienKorelasi(int ukuranPopulasi) : this()
        {
            this.ukuranPopulasi = ukuranPopulasi;
        }
        #endregion

        /// <summary>
        /// Menambahkan X ke dalam list
        /// </summary>
        /// <param name="skorItem">X</param>
        public void TambahSkorItem(int skorItem)
        {
            // Menambahkan X
            this.skorItem.Add(skorItem);

            // Menambahkan X kuadrat
            this.skorItemKuadrat.Add((int)Math.Pow((double)skorItem, 2.0));
        }

        /// <summary>
        /// Menambahkan Y ke dalam list
        /// </summary>
        /// <param name="skorTotalItem">Y</param>
        public void TambahSkorTotalItem(int skorTotalItem)
        {
            // Menambahkan Y
            this.skorTotalItem.Add(skorTotalItem);

            // Menambahkan Y kuadrat
            this.skorTotalItemKuadrat.Add((int)Math.Pow((double)skorTotalItem, 2.0));
        }

        /// <summary>
        /// Menghitung koefisien korelasi
        /// </summary>
        /// <returns>Koefisien korelasi</returns>
        public double HitungKoefisienKorelasi()
        {
            int sigmaXY = SigmaXY();
            int sigmaX = SigmaX();
            int sigmaY = SigmaY();
            int sigmaXKuadrat = SigmaXKuadrat();
            int sigmaYKuadrat = SigmaYKuadrat();

            double hitungPembilang = (this.ukuranPopulasi * sigmaXY) - (sigmaX * sigmaY);
            double hitungPenyebut = Math.Sqrt(((this.ukuranPopulasi * sigmaXKuadrat) - Math.Pow(sigmaX, 2.0))
                * ((this.ukuranPopulasi * sigmaYKuadrat) - Math.Pow(sigmaY, 2.0)));

            return hitungPembilang / hitungPenyebut;
        }

        #region Private Methods
        /// <summary>
        /// Menghitung Sigma
        /// </summary>
        /// <param name="nilai">List dari nilai</param>
        /// <returns></returns>
        private int Sigma(List<int> nilai)
        {
            int hasil = 0;
            nilai.ForEach(item => hasil += item);

            return hasil;
        }

        /// <summary>
        /// Menghitung Sigma X
        /// </summary>
        /// <returns>Sigma X</returns>
        private int SigmaX()
        {
            return Sigma(this.skorItem);
        }

        /// <summary>
        /// Menghitung Sigma X Kuadrat
        /// </summary>
        /// <returns>Sigma X Kuadrat</returns>
        private int SigmaXKuadrat()
        {
            return Sigma(this.skorItemKuadrat);
        }

        /// <summary>
        /// Menghitung Sigma Y
        /// </summary>
        /// <returns>Sigma Y</returns>
        private int SigmaY()
        {
            return Sigma(this.skorTotalItem);
        }


        /// <summary>
        /// Menghitung Sigma Y Kuadrat
        /// </summary>
        /// <returns>Sigma Y Kuadrat</returns>
        private int SigmaYKuadrat()
        {
            return Sigma(this.skorTotalItemKuadrat);
        }

        /// <summary>
        /// Menghitung Sigma X * Y
        /// </summary>
        /// <returns>Sigma X * Y</returns>
        private int SigmaXY()
        {
            int hasil = 0;

            for (int i = 0; i < this.skorItem.Count; i++)
                hasil += this.skorItem[i] * this.skorTotalItem[i];

            return hasil;
        }

        #endregion
    }
}